package com.zjb.demo.common.controller;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.zjb.demo.common.constant.CacheConstants;
import com.zjb.demo.common.domain.LoginUser;
import com.zjb.demo.common.domain.response.AjaxResult;
import com.zjb.demo.system.domain.SysUserOnline;
import com.zjb.demo.system.service.SysUserOnlineService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.noear.redisx.RedisClient;
import org.noear.solon.annotation.*;

import java.util.ArrayList;
import java.util.Objects;

/**
 * 在线用户监控
 *
 * @author 庄佳彬
 * @since 2023/12/26 21:48
 */
@Controller
@Api(tags = "在线用户监控")
@Mapping("/monitor/online")
public class SysUserOnlineController {
    @Inject
    private SysUserOnlineService userOnlineService;
    @Inject
    private RedisClient redisClient;

    @Get
    @Mapping("/list")
    @ApiOperation(value = "在线用户列表")
    public AjaxResult<Page<SysUserOnline>> list(
            @Param(name = "ipaddr") String ipaddr,
            @Param(name = "userName") String userName
    ) {
        var bucket = redisClient.getBucket();
        var keys = bucket.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        var userOnlineList = new ArrayList<SysUserOnline>();
        for (String key : keys) {
            var user = bucket.getAndDeserialize(key, LoginUser.class);
            if (StrUtil.isNotEmpty(ipaddr) && StrUtil.isNotEmpty(userName)) {
                if (Objects.equals(ipaddr, user.getIpaddr()) && Objects.equals(userName, user.getUsername())) {
                    userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
                }
            } else if (StrUtil.isNotEmpty(ipaddr)) {
                if (Objects.equals(ipaddr, user.getIpaddr())) {
                    userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
                }
            } else if (StrUtil.isNotEmpty(userName)) {
                if (Objects.equals(userName, user.getUsername())) {
                    userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
                }
            }
            userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
        }
        var page = new Page<SysUserOnline>(1, userOnlineList.size(), userOnlineList.size());
        page.setRecords(userOnlineList);
        return AjaxResult.success(page);
    }

    @Delete
    @Mapping("/{tokenId}")
    @ApiOperation(value = "强制下线")
    public AjaxResult<Void> forceLogout(String tokenId) {
        redisClient.getBucket().remove(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
        return AjaxResult.success();
    }
}
